package com.cy.study.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cy.study.entity.ExamEntity;
import com.cy.study.entity.ExamRecordEntity;
import com.cy.study.entity.QuestionEntity;
import com.cy.study.entity.UserExamRecordEntity;
import com.cy.study.exception.BusinessException;
import com.cy.study.mapper.QuestionMapper;
import com.cy.study.mapper.UserExamRecordMapper;
import com.cy.study.req.QuestionAddReq;
import com.cy.study.req.QuestionDeleteReq;
import com.cy.study.req.UserSubmitExamReq;
import com.cy.study.res.UserExamDetailRes;
import com.cy.study.service.ExamRecordService;
import com.cy.study.service.ExamService;
import com.cy.study.service.QuestionService;
import com.cy.study.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

@Service
@Slf4j
@RequiredArgsConstructor
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, QuestionEntity> implements QuestionService {

    private final ExamService examService;
    private final ExamRecordService examRecordService;

    private final UserExamRecordMapper userExamRecordMapper;


    private void resetQuestionSort(Integer examId){
        AtomicReference<Integer> count = new AtomicReference<>(1);
        QueryWrapper<QuestionEntity> questionWrapper = new QueryWrapper<>();
        questionWrapper.lambda().eq(QuestionEntity::getExamId,examId)
                .orderByAsc(QuestionEntity::getId);
        List<QuestionEntity> list = this.getBaseMapper().selectList(questionWrapper);
        list.stream().forEach(e->{
            e.setQuestionNum(count.get());
            count.getAndSet(count.get() + 1);
        });
        this.saveOrUpdateBatch(list);
    }

    @Override
    public Integer addQuestion(QuestionAddReq req) {
        QuestionEntity question = new QuestionEntity();
        BeanUtils.copyProperties(req,question);
        this.save(question);
        resetQuestionSort(req.getExamId());
        return question.getId();
    }

    @Override
    public void deleteQuestion(QuestionDeleteReq req) {
        QuestionEntity question = this.getBaseMapper().selectById(req.getId());
        Integer examId = question.getExamId();
        QueryWrapper<UserExamRecordEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UserExamRecordEntity::getExamId,examId);
        Long count = userExamRecordMapper.selectCount(wrapper);
        if(count>0){
            throw new BusinessException("已经有用户做题记录,不允许删除");
        }
        this.removeById(req.getId());
        resetQuestionSort(question.getExamId());
    }

    @Override
    public UserExamDetailRes userExamDetail(Integer examId) {
        UserExamDetailRes res = new UserExamDetailRes();
        ExamEntity exam = examService.getBaseMapper().selectById(examId);
        res.setExam(exam);
        QueryWrapper<QuestionEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(QuestionEntity::getExamId,examId);
        List<QuestionEntity> questions = this.getBaseMapper().selectList(wrapper);
        res.setQuestions(questions);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void userSubmitExam(UserSubmitExamReq req) {
        Integer examId = req.getExamId();
        Integer userId = SecurityUtils.getUserId();
        //先插用户做题记录
        UserExamRecordEntity entity = new UserExamRecordEntity();
        entity.setExamId(req.getExamId());
        entity.setUserId(userId);
        entity.setFinishTime(LocalDateTime.now());
        userExamRecordMapper.insert(entity);
        List<ExamRecordEntity> examList = new ArrayList<>();
        req.getQuestions().stream().forEach(e->{
            ExamRecordEntity record = new ExamRecordEntity();
            record.setUserId(userId);
            record.setExamRecordId(entity.getId());
            record.setPracticeId(e.getId());
            record.setUserAnswer(e.getUserAnswer());
            record.setCreateTime(LocalDateTime.now());
            examList.add(record);
        });
        boolean b = examRecordService.saveOrUpdateBatch(examList);
        System.out.println(b);
    }
}
